package com.qf.springbootproject.product.service.impl;


import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.springbootproject.es.SelectEsVo;
import com.qf.springbootproject.product.entity.ProductParams;
import com.qf.springbootproject.product.mapper.ProductParamsMapper;
import com.qf.springbootproject.product.service.ProductParamsService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 商品参数  服务实现类
 * </p>
 *
 * @author yyq
 * @since 2023-02-14
 */
@Service
public class ProductParamsServiceImpl extends ServiceImpl<ProductParamsMapper, ProductParams> implements ProductParamsService {
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 商品生产信息
     *
     * @param id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ProductParams productAcclaim(Integer id) {
        ProductParams productParams = getOne(new QueryWrapper<ProductParams>().eq("product_id", id));
        return productParams;
    }

    @Override
    public void insertProduct(ProductParams productParams) {
        productParams.setCreateTime(LocalDateTime.now());
        productParams.setUpdateTime(LocalDateTime.now());
        save(productParams);
    }

    @Override
    public void sendProductEs(ProductParams productParams) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String product = objectMapper.writeValueAsString(productParams);
        rabbitTemplate.convertAndSend("product_exchange", "product.1.1", product);
    }

    @Override
    public List<Map<String, Object>> boolQuery(SelectEsVo selectEsVo) {
        // 构造 BoolQueryBuilder
        final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 设置must
        boolQueryBuilder.must(new MatchQueryBuilder(selectEsVo.getMatchField(), selectEsVo.getMatchValue()));
        // 设置加分字段和boost值
        boolQueryBuilder.should(new TermQueryBuilder(selectEsVo.getTermField(), selectEsVo.getTermValue()).boost(Float.valueOf(selectEsVo.getBoost())));
        // ===========以代码形式声明Bool查询 end===================
        final NativeSearchQuery searchQuery = new NativeSearchQuery(boolQueryBuilder);
        // 设置索引
        searchQuery.addIndices(selectEsVo.getIndex());
        final SearchResponse response = elasticsearchRestTemplate.query(searchQuery, new ResultsExtractor<SearchResponse>() {
            @Override
            public SearchResponse extract(SearchResponse response) {
                return response;
            }
        });
        System.out.println(response);
        // 跟前端约定，是否可以直接返回 hits数组，因为数据是全的，只是多出几个es的默认json字段。
        // 如果可以则无需继续处理数据，接口直接返回 hists
        final SearchHit[] hits = response.getHits().getHits();
        // 如果只要json文档的list，那么继续处理数据
        final ArrayList<Map<String, Object>> resultList = new ArrayList<>();
        for (SearchHit hit : hits) {
            final Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            resultList.add(sourceAsMap);
        }
        return resultList;
    }


}
